#encoding:utf-8
'''
Created on March 10 2014

@author: yangluo
'''

import wx
import os
import socket
import threading

window_size =(550,380)
child_win_size = (300,200)
button_size = (70,30)

frame_color = wx.Color(255,255,255)
text_color  = wx.Color(40,139,213)



class MyFrame(wx.Frame):
    def __init__(self, parent=None,id=-1,
                   pos=wx.DefaultPosition,title='CHATTOR_SERVER'):
        wx.Frame.__init__(self,parent,id,title,pos,size=window_size)
        
class childFrame(wx.Frame):
    def __init__(self,image,parent=None,id=-1,
                 pos=wx.DefaultPosition,title='new'):
        temp = image.ConvertToBitmap()
        size = temp.GetWidth(), temp.GetHeight()
        wx.Frame.__init__(self, parent, id, title, pos, size)
        panel = wx.Panel(self)
        self.bmp = wx.StaticBitmap(parent=panel, bitmap=temp)
        self.SetClientSize(size)
        
class MyApp(wx.App):
    def __init__(self,port=5757,redirect=True):
        wx.App.__init__(self,redirect)
        
        self.user_dict= {}    #pair: (int)userno, (str)username
        self.user_count = 0
        
        self.targetDir = ''
        self.targetFile = ''
        self.targetPath = ''
        self.sendfilepath  = ''
        self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        #self.ip=socket.getaddrinfo(socket.gethostname(),None)[-2][4][0]
        self.ip = socket.gethostbyname(socket.gethostname())
        self.port = port
        self.conn = ''
        self.conductType = ''
        
        #create thread 
        self.userThreadList = []
        self.connList = []
        #self.keythread_handle = threading.Thread(target=self.conductThread)
        self.socketThread_handle = threading.Thread(target=self.socketThread)
        self.socketThread_handle.start()
    
    def OnInit(self):
        self.win = MyFrame()
        bkg = wx.Panel(self.win)
        bkg.SetBackgroundColour(frame_color)
        winFont = wx.Font(15,wx.MODERN,wx.NORMAL,wx.NORMAL)
        self.Bind(wx.EVT_CLOSE,self.CloseWindow)
        
        ST_ip = wx.StaticText(bkg,-1,'ip:     ')
        self.ip_text = wx.TextCtrl(bkg)
        self.ip_text.SetEditable(False)
        self.ip_text.SetValue(str(socket.getaddrinfo(socket.gethostname(),None)[-2][4][0]) + ':' +'5757')
        ST_ip.SetFont(winFont)
        self.ip_text.SetFont(winFont)
        
        ip_hbox = wx.BoxSizer()
        ip_hbox.Add(ST_ip, proportion=2,flag=wx.ALIGN_LEFT)
        ip_hbox.Add(self.ip_text,proportion=5,flag=wx.ALIGN_LEFT)
        
#         ST_filepath = wx.StaticText(bkg,-1,"path:")
#         self.filepath = wx.TextCtrl(bkg)
#         self.browser = wx.Button(bkg,label='browser')
#         self.browser.Bind(wx.EVT_BUTTON,self.Browser)
#         ST_filepath.SetFont(winFont)
#         self.filepath.SetFont(winFont)
#         self.browser.SetFont(winFont)
        
        self.messageList = wx.ListBox(bkg,style=wx.MULTIPLE | wx.HSCROLL,size=(300,200))
        self.messageList.SetForegroundColour(text_color)
        
        #listbox_size = (400,450)
        self.messageList.SetFont(winFont)
        listItem = ['wechat:']
        self.messageList.InsertItems(listItem,0)
        
        #self.messageList.SetSize(listbox_size)
        self.chat = wx.TextCtrl(bkg)
        self.send = wx.Button(bkg,label="send")
        self.send.Bind(wx.EVT_BUTTON, self.SendMessage)
        self.chat.SetFocus()
        self.chat.SetFont(winFont)
        self.send.SetFont(winFont)
        
        
       # hbox1 = wx.BoxSizer()
#         hbox1.Add(ST_filepath, proportion=1)
#         hbox1.Add(self.filepath,proportion=2,border=5)
#         hbox1.Add(self.browser,proportion=1,border=5)
        
        vbox1_2 = wx.BoxSizer(wx.VERTICAL)
        vbox1_2.Add(ip_hbox, proportion=1, flag=wx.ALIGN_CENTER,border=5)
        #vbox1_2.Add(hbox1,proportion=1,flag=wx.ALIGN_CENTER,border=5)
        
        vbox2 = wx.BoxSizer(wx.VERTICAL)
        vbox2.Add(self.messageList, proportion=0,flag=wx.EXPAND,border=5)
        
        hbox3 = wx.BoxSizer()
        hbox3.Add(self.chat,proportion=1,flag=wx.ALIGN_CENTER)
        hbox3.Add(self.send,proportion=0,flag=wx.ALIGN_CENTER)
        
        total_box = wx.BoxSizer(wx.VERTICAL)
        #total_box.Add(hbox1,proportion=1,flag=wx.ALIGN_CENTER)
        total_box.Add(vbox1_2,proportion=1,flag=wx.EXPAND|wx.ALL,border=8)
        total_box.Add(vbox2,proportion=5,flag=wx.EXPAND|wx.ALL,border=5)
        total_box.Add(hbox3,proportion=1,flag=wx.EXPAND|wx.ALL,border=8)
        bkg.SetSizer(total_box)
        
        self.win.Show()
        return True
    def CloseWindow(self,event):
        #self.send('close,%d'%self.userno)
        self.sock.close()
    
#     def Browser(self,event):
#         default_save_filename = "you_havent_named_this_file.zip"
#         fdlg = wx.FileDialog(self.win, "open file",os.getcwd(), style=wx.OPEN)
#         self.sourcefiledir = fdlg.GetDirectory()
#         #fdlg.SetFilename(default_save_filename)
#         
#         if fdlg.ShowModal() == wx.ID_OK:
#             self.targetDir = fdlg.GetDirectory()
#             self.targetFile = fdlg.GetFilename()
#             self.targetPath = self.targetDir + '\\' + self.targetFile
#             fdlg.Destroy()
#             self.filepath.SetValue(self.targetPath)
#             default_save_filename = self.targetDir.split('\\')[-1] +".zip"
#             self.sendfilepath = self.targetDir+'\\' + default_save_filename
#             #print self.targetDir.split('\\')[-1]
#             zipModule.zipfolder(self.targetDir,  self.sendfilepath )
#             
#             if not os.path.isfile(self.targetPath):
#                 print 'not a path'
#             
        
    def SendMessage(self,event):
        newMsg = self.chat.GetValue()
        if newMsg == '':
            return
        else:
            sendMsg = 'toall,service:, '+ newMsg
            # send the message to all clients
            for conn in self.connList:
                conn.send(sendMsg)
                
#             self.conn.send(sendMsg)
            item =['me   : ' + newMsg]
            self.messageList.AppendItems(item)
            self.messageList.Select(self.messageList.GetCount()-1)
            self.chat.SetValue('')
        
    def listen(self):
        
        conn, addr = self.sock.accept()
        conn.settimeout(60000)
        userapply = conn.recv(16)
        if userapply.split(',')[0] == 'apply':
            conn.send('ok,%d'%(self.user_count))
            self.user_dict.setdefault(self.user_count,userapply.split(',')[1])
            self.connList.append(conn)
            self.user_count += 1
            item = ['---->User%d join you !'%(self.user_count-1)]
            self.messageList.AppendItems(item)
            return (self.user_count-1)
        else:
            conn.send('deny!')
            return -1
        
        
#     def send(self):
#         if self.sendfilepath == '':
#             print 'self.sendfilepath is none'
#             return False
# #         print 'sending...'
#         size=os.path.getsize(self.sendfilepath)
#         apply = "commit,"+str(size)
#         self.conn.send(apply)
#         recvMag = self.conn.recv(50)
#         if recvMag != 'ok':
#             print "request faild"
#             return False
#         
#         fp = open(self.sendfilepath)
#         while True:
#             filedata = fp.read(1024)
#             if not filedata:
#                 break
#             self.conn.send(filedata)
#             
# #         print 'sending over...'
#         fp.close()
#         #self.sock.close()
#     def recvfiles(self,save_path="E:\\Internet.zip"):
# #         print 'recv'
#         msg = self.conn.recv(20)
# #         print 'msg is ' + msg
#     
    def recvMsg(self):
        # this user's thread
        thisuserno = self.user_count-1

        while True:
            # check if this client send message to service
                tmp_msg = self.connList[thisuserno].recv(100)
                #after 60000s time out
                self.connList[thisuserno].settimeout(60000)       
                if tmp_msg == '':
                    continue
                else:
                    # this client send message to service
                    # analysis if the message is legal
                    if tmp_msg.split(',')[0] == 'toall':
                        current_userno = int(tmp_msg.split(',')[1])
                        newMsg = tmp_msg.split(',')[-1]
                        item = ['user'+str(current_userno)+': '+newMsg]
                        self.messageList.AppendItems(item)
                        self.messageList.Select(self.messageList.GetCount()-1)
                        # the message is legal so send this message to other clients
                        for conn in self.connList:
                            if conn == self.connList[thisuserno] :
                                continue
                            conn.send('toall,user'+str(thisuserno)+': ,'+newMsg)
                    elif tmp_msg.split(',')[0] == 'close':
                        del self.connList[thisuserno]
                        return

    def socketThread(self): 
        self.sock.bind((self.ip,self.port))
        self.sock.listen(50)
        isConnect = -1
        while True:
            isConnect = self.listen()
            
            # each valid client has its own thread 
            if isConnect != -1:
                userThread_handle = threading.Thread(target=self.recvMsg)
                self.userThreadList.append(userThread_handle)
                userThread_handle.start()

def main():
    app = MyApp()
    app.MainLoop()

if __name__ == '__main__':
    main()






